/*jslint maxerr: 50, indent: 4, browser: true */
/*global define */

(function () {
    "use strict";

    define("dom", ["mergeModules", "init", "array"], function (make) {
        var buri = make.mergeModules(arguments),
            config = {
                "compatability": {}
            },
            classList;

        function addEventListener(node, type, func) {
            var handler;

            if (node.addEventListener) {
                node.addEventListener(type, func, false);
            } else if (node.attachEvent) {
                node["e" + type + func] = func;
                node[type + func] = function () {
                    node["e" + type + func](window.event);
                };

                node.attachEvent("on" + type, node[type + func]);
            } else {
                handler = node["on" + type];
                if (typeof handler === "function") {
                    node["on" + type] = function (evt) {
                        handler(evt);
                        func(evt);
                    };
                } else {
                    node["on" + type] = func;
                }
            }
        }

        function removeEventListener(node, type, fni) {
            if (node.removeEventListener) {
                node.removeEventListener(type, fni, false);
            } else if (node.detachEvent) {
                node.detachEvent("on" + type, node[type + fni]);
                node[type + fni] = null;
            }
        }

        function clickNode(node) {
            var evt = document.createEvent("MouseEvents");

            evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);

            return node.dispatchEvent(evt);
        }

        function emptyNode(node) {
            while (node.firstChild) {
                node.removeChild(node.firstChild);
            }
        }

        function getElementsByClassName(node, className) {
            if (typeof node.getElementsByClassName === "function") {
                return node.getElementsByClassName(className);
            }

            var array = [],
                regex = new RegExp("(^| )" + className + "( |$)"),
                elements = node.getElementsByTagName("*"),
                length = elements.length,
                i = 0,
                element;

            while (i < length) {
                element = elements[i];
                if (regex.test(element.className)) {
                    buri.array.push(array, element);
                }

                i += 1;
            }

            return array;
        }

        classList = {
            "contains": function (node, className) {
                if (node.classList && node.classList.contains) {
                    return node.classList.contains(className);
                }

                return buri.array.contains(buri.string.split(node.className, " "), className);
            },

            "add": function (node, className) {
                if (node.classList && node.classList.add) {
                    node.classList.add(className);
                    return;
                }

                var classList;

                if (!classList.contains(node, className)) {
                    classList = buri.string.split(node.className, " ");
                    buri.array.push(classList, className);
                    node.className = buri.array.join(classList, " ");
                }
            },

            "remove": function (node, className) {
                if (node.classList && node.classList.remove) {
                    node.classList.remove(className);
                    return;
                }

                var hasClass = classList.contains(node, className),
                    tempList,
                    listClass,
                    name;

                if (hasClass) {
                    tempList = buri.array.split(node.className, " ");
                    hasClass = buri.array.contains(tempList, className);
                    listClass = [];
                    while (hasClass) {
                        name = buri.array.shift(tempList);
                        if (name !== className) {
                            buri.array.push(listClass, name);
                        }

                        hasClass = buri.array.contains(tempList, className);
                    }

                    node.className = buri.array.join(listClass, " ");
                }
            },

            "toggle": function (node, className) {
                if (node.classList && node.classList.toggle) {
                    node.classList.toggle(className);
                }

                if (classList.contains(node, className)) {
                    classList.remove(node, className);
                } else {
                    classList.add(node, className);
                }
            }
        };

        return {
            "dom": {
                "init": function (options) {
                    buri.init(config, options);
                    buri.array.init(config);
                },
                "addEventListener": addEventListener,
                "removeEventListener": removeEventListener,
                "clickNode": clickNode,
                "classList": classList,
                "emptyNode": emptyNode,
                "getElementsByClassName": getElementsByClassName
            }
        };
    });
}());
